﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Text;
public class CardList : List<Card>
{
	public CardList()
	{

	}
	public CardList(Card[] cards)
	{
		this.AddRange(cards);
	}
	public CardList(List<Card> cards)
	{
		this.AddRange(cards);
	}
	public static CardList FilterRemoveCards(CardList list,CardList remove_list) {
		return new CardList(list.Where(card => !remove_list.Contains(card)).ToArray());
	}
	static public implicit operator CardList(Card[] list) { return new CardList(list); }
	//static public implicit operator CardList(IEnumerable<Card> list) { return new CardList(list.ToArray()); }
	private List<Card> disabled_list = new List<Card>();
	public new void Add(Card card)
	{
		if (card != null)
		{
			base.Add(card);
		}
		else
		{
			Console.WriteLine("CardBox Add Empty Card!");
		}
	}
	public bool HasCardByNumber(string number, out Card res_card, out Card is_use_laizi_card)
	{
		is_use_laizi_card = null;
		res_card = null;

		foreach (var card in this)
		{
			if (card.Number == number)
			{
				res_card = card;
				break;
			}
		}
		if (res_card == null)
		{
			foreach (var card in this)
			{
				if (card.IsAny)
				{
					is_use_laizi_card = card;
					res_card = card;
					break;
				}
			}
		}
		return res_card != null;
	}
	public bool HasCardByNumber(string number, out bool is_use_any)
	{
		Card is_use_laizi_card;
		Card res_card;
		var res = this.HasCardByNumber(number, out res_card, out is_use_laizi_card);
		is_use_any = is_use_laizi_card != null;
		return res;
	}
	public bool HasCardByNumber(string number)
	{
		bool _;
		return this.HasCardByNumber(number, out _);
	}
	public bool HasCardsByNumber(string[] numbers, out bool is_use_any)
	{

		is_use_any = false;
		Card is_use_laizi_card;
		Card find_card;
		var res = true;
		foreach (var number in numbers)
		{
			if (this.HasCardByNumber(number, out find_card, out is_use_laizi_card))
			{
				this.DisableCard(find_card);
				if (is_use_laizi_card != null)
				{
					is_use_any = true;
				}
			}
			else
			{
				res = false;
				break;
			}
		}
		this.disabled_list.Clear();
		return res;
	}
	public bool HasCardsByNumber(string[] numbers)
	{
		bool _;
		return this.HasCardsByNumber(numbers, out _);
	}
	public Card GetCard(string txt)
	{
		var res = this.Find(card =>
			{
				if (card.ToString() == txt
					&& !this.disabled_list.Contains(card))
				{
					return true;
				}
				return false;
			});
		return res;
	}
	public bool HasCard(string txt)
	{
		return this.GetCard(txt) != null;
	}
	public bool HasCard(string txt, out bool is_use_any)
	{
		Card is_use_laizi_card;
		Card res_card;
		var res = this.HasCard(txt, out res_card, out is_use_laizi_card);
		is_use_any = is_use_laizi_card != null;
		return res;
	}
	public bool HasCard(string txt, out Card res_card, out Card is_use_laizi_card)
	{
		is_use_laizi_card = null;
		res_card = null;
		var target_card = Card.GetIns(txt);
		if (target_card == null)
		{
			throw new Exception("未知卡牌：" + txt);
		}
		res_card = this.GetCard(txt);
		if (res_card == null)
		{
			foreach (var card in this)
			{
				if (card.IsAny)
				{
					if (
						(card.Type == "大" && (target_card.Type == "红心" || target_card.Type == "方块"))
						||
						(card.Type == "小" && (target_card.Type == "黑桃" || target_card.Type == "梅花"))
					)
					{
						is_use_laizi_card = card;
						res_card = card;
						break;
					}
				}
			}
		}
		return res_card != null;
	}
	public bool DisableCard(string txt)
	{
		var target_card = this.GetCard(txt);
		if (target_card == null)
		{
			return false;
		}
		this.disabled_list.Add(target_card);
		return true;
	}
	public void DisableCard(Card card)
	{
		this.disabled_list.Add(card);
	}
	public bool EnableCard(string txt)
	{
		var target_card = this.disabled_list.Find(card =>
			{
				if (card.ToString() == txt)
				{
					return true;
				}
				return false;
			});
		if (target_card == null)
		{
			return false;
		}
		this.disabled_list.Remove(target_card);
		return true;
	}
	public void ClearDisabledCards() { this.disabled_list.Clear(); }
	public bool HasCards(string[] txt_list, out bool is_use_any)
	{
		is_use_any = false;
		Card is_use_laizi_card;
		Card find_card;
		var res = true;
		foreach (var txt in txt_list)
		{
			if (this.HasCard(txt, out find_card, out is_use_laizi_card))
			{
				this.DisableCard(find_card);
				if (is_use_laizi_card != null)
				{
					is_use_any = true;
				}
			}
			else
			{
				res = false;
				break;
			}
		}
		this.disabled_list.Clear();
		return res;
	}
	public bool HasCards(string[] txt_list)
	{
		bool _;
		return this.HasCards(txt_list, out _);
	}
	public List<Card> GetCardsByNumber(string number, bool with_laizi = true)
	{
		var res = new List<Card>();

		foreach (var card in this)
		{
			if ((with_laizi && card.IsAny || card.Number == number)
				&&
				!this.disabled_list.Contains(card))
			{
				res.Add(card);
			}
		}
		return res;
	}
	public List<Card> GetCardsByType(string type, bool with_laizi = true, bool with_extend_type = true)
	{
		var res = new List<Card>();
		var color = Card.GetColorByType(type);
		foreach (var card in this)
		{
			if (
				(
					(with_laizi && card.IsAny && card.Color == color)
					||
					(with_extend_type ? card.Type.StartsWith(type) : (card.Type == type))
				)
				&&
				!this.disabled_list.Contains(card)
			)
			{
				res.Add(card);
			}
		}
		return res;
	}
	public List<Card> GetLaiziCards()
	{
		var res = new List<Card>();
		foreach (var card in this)
		{
			if (card.IsAny && !this.disabled_list.Contains(card))
			{
				res.Add(card);
			}
		}
		return res;
	}
	public bool HasLaiziCard()
	{
		foreach (var card in this)
		{
			if (card.IsAny && !this.disabled_list.Contains(card))
			{
				return true;
			}
		}
		return false;
	}
}